<template>
  <div class="todoapp">
    <TodoHeader :list="list" @changeAll="changeAll" @addTodo="addTodo" />
    <TodoMain
      :list="list"
      :status="status"
      @delById="delById"
      @changeDone="changeDone"
    />
    <TodoFooter
      :list="list"
      :status="status"
      @clearDone="clearDone"
      @changeStatus="changeStatus"
    />
  </div>
</template>

<script setup lang="ts">
/**
 *  学习目标：Todos 案例
 *    1. 拆分组件(头部，主体，底部)
 *    2. 初始化列表数据，并渲染到主体组件中
 *    3. 主体 - 根据 id 删除数据
 *    4. 主体 - 根据 id 更新完成状态
 *    5. 底部 - 删除已完成任务
 *    6. 底部 - 计算剩余任务数量
 *    7. 底部 - 高亮切换效果
 *    8. 主体 - 计算显示列表(全部显示/未完成/已完成)
 *    9. 主体 - 计算全选状态，切换全选状态
 *    10. 头部 - 获取输入框数据，按回车键，新增待办任务
 *    11. 数据初始化时 - 获取本地存储数据
 *    12. 数据被更新时 - 设置本地存储数据
 */
import { Status, Todo } from './types'
import TodoHeader from './components/TodoHeader.vue'
import TodoMain from './components/TodoMain.vue'
import TodoFooter from './components/TodoFooter.vue'
import { ref } from '@vue/reactivity'
import { watch } from '@vue/runtime-core'
// 2. 初始化列表数据
// 11. 数据初始化时 - 获取本地存储数据
const list = ref<Todo[]>(
  JSON.parse(localStorage.getItem('todos-list') || '[]')
)
const status = ref<Status>(
  (localStorage.getItem('todos-status') as Status) || 'all'
)
// 3. 根据 id 删除数据
const delById = (id: number) => {
  const index = list.value.findIndex((v) => v.id === id)
  list.value.splice(index, 1)
}
// 4. 根据 id 更新完成状态
const changeDone = (id: number) => {
  const todo = list.value.find((v) => v.id === id)
  if (todo) {
    todo.done = !todo?.done
  }
}
// 5. 删除已完成任务
const clearDone = () => {
  list.value = list.value.filter((v) => !v.done)
}
// 6. 底部组件 - 计算剩余任务数量

// 7. 高亮切换效果
const changeStatus = (value: Status) => {
  status.value = value
}
// 8. 主体组件 - 计算显示列表(全部显示/未完成/已完成)

// 9. 切换全选状态
const changeAll = (value: boolean) => {
  list.value = list.value.map((v) => ({ ...v, done: value }))
}

// 10. 新增待办任务
const addTodo = (content: string) => {
  const todo: Todo = { id: Date.now(), content: content, done: false }
  list.value.unshift(todo)
}

// 12. 数据被更新时 - 设置本地存储数据
watch(list.value, () => {
  localStorage.setItem('todos-list', JSON.stringify(list.value))
})
watch(status, () => {
  localStorage.setItem('todos-status', status.value)
})
</script>
